package utils

import (
	"encoding/json"
	"fmt"
	"dockerui/models"
	"github.com/shirou/gopsutil/cpu"
	"net"
	"os"
)



func GetIPs() (ips []string) {
	/* get machine ips */
	interfaceAddr, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Printf("fail to get net interface addrs: %v", err)
		return ips
	}

	for _, address := range interfaceAddr {
		ipNet, isValidIpNet := address.(*net.IPNet)
		if isValidIpNet && !ipNet.IP.IsLoopback() {
			if ipNet.IP.To4() != nil {
				ips = append(ips, ipNet.IP.String())
			}
		}
	}
	return ips
}

func getHostName() string {
	var (
		hostname string
		err error
	)

	hostname, err = os.Hostname()
	if err != nil {
		fmt.Print("get hostname error")
		return ""
	}
	return hostname
}

func getCpuCore() models.CpuInfo{
	var (
		data []byte
		cpuInfoMap map[string]interface{}
		err error
		modelName string
		cpuInfo models.CpuInfo
	)
	physicalCnt, _ := cpu.Counts(false)
	logicalCnt, _ := cpu.Counts(true)
	infos, _ := cpu.Info()
	for _, info := range infos {
		data, _ = json.MarshalIndent(info, "", " ")
		//fmt.Print(string(data))
	}
	if cpuInfoMap, err = JsonToMap(string(data)); err != nil {
		modelName = ""
	}
	// interface convert string
	modelName = cpuInfoMap["modelName"].(string)
	cpuInfo = models.CpuInfo{
		PhysicalCnt: physicalCnt,
		LogicalCnt:  logicalCnt,
		ModelName:   modelName,
	}
	return cpuInfo
}

func GetMachineInfo() models.MachineInfo{
	var (
		machineInfo models.MachineInfo
	)
	machineInfo = models.MachineInfo{
		HostName: getHostName(),
		Ips: GetIPs(),
		CpuInformation: getCpuCore(),
	}
	return machineInfo
}

func JsonToMap(jsonStr string) (map[string]interface{}, error) {
	var (
		m map[string]interface{}
		err error
	)
	m = make(map[string]interface{})
	err = json.Unmarshal([]byte(jsonStr), &m)
	if err != nil {
		fmt.Printf("Unmarshal with error: %+v\n", err)
		return nil, err
	}
	return m, nil
}

func LimitVerify(skip int, limit int, dataLen int) (int, int) {
	var (
		pageCount int
		itemRemain int
	)
	if dataLen == 1{
		return 0, 1
	} else if dataLen == 0 {
		return 0, 0
	} else{
		pageCount = dataLen / limit
		if skip > pageCount {
			return -1, -1
		} else {
			if (skip + 1) * limit <= dataLen {
				return skip * limit, (skip * limit) + limit
			}else {
				itemRemain = dataLen - (skip * limit)
				// 如果为第一页
				if skip >= 1 {
					return pageCount * limit , (pageCount * limit) + itemRemain
				} else {
					return 0, itemRemain
				}

			}
		}
	}
}


func MaptoString(originMap map[string]interface{}) string {
	var (
		resJson []byte
		res string
	)
	resJson, _ = json.Marshal(originMap)
	res = string(resJson)
	return res
}

func RemoveDuplicatedElem(originRes []map[string]interface{}) []map[string]interface{} {
	var (
		res []map[string]interface{}
		repeat bool
	)

	for i := 0; i < len(originRes); i++ {
		repeat = false
		for j := i+1; j < len(originRes); j ++ {
			if MaptoString(originRes[i]) == MaptoString(originRes[j]) {
				repeat = true
				break
			}
		}
		if !repeat {
			res = append(res, originRes[i])
		}
	}
	return res
}


func formatFileSize(fileSize int64) (size string) {
	if fileSize < 1024 {
		return fmt.Sprintf("%.2fB", float64(fileSize)/float64(1))
	} else if fileSize < (KB) {
		return fmt.Sprintf("%.2fKB", float64(fileSize)/float64(B))
	} else if fileSize < (MB) {
		return fmt.Sprintf("%.2fMB", float64(fileSize)/float64(KB))
	} else if fileSize < (GB) {
		return fmt.Sprintf("%.2fGB", float64(fileSize)/float64(MB))
	} else if fileSize < (TB) {
		return fmt.Sprintf("%.2fTB", float64(fileSize)/float64(GB))
	} else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024)
		return fmt.Sprintf("%.2fEB", float64(fileSize)/float64(TB))
	}
}